; ******************************************************************************
; * led_cycle.asm
; * LLP STUDIO SVP Peng
; * V1.0
; * 2023-08-31
; * P2口8个LED轮流点亮，每个管亮100 ms
; * 100 ms / 1 μs = 100000 次
; * 由于超过了最大溢出值，取一半用软件计数器实现
; * 选择定时器Timer1工作方式1，定时器最大计数值：2^16 = 65536 = 0FFFFH + 1
; * 初值：65536 - 50000 = 15536 = 3CB0H
; ******************************************************************************

ORG 0000H

; 方法一：查询方式
;MOV A, #0FEH

;Next:
;MOV P2, A  ; LED1亮
;MOV TMOD, #10H  ; Timer1工作于定时方式1
;MOV TH1, #3CH
;MOV TL1, #0B0H  ; 定时50 ms
;SETB TR1  ; 启动Timer1工作
;MOV R0, #2 ; 软件计数器R0设为2

;Loop:
;JBC TF1, SHI  ; 计时溢出，则TCON中的TF = 1，并由CPU自动清TF1
;SJMP Loop  ; 未溢出，再次检查TF1

;SHI:
;;CLR TR1  ; 停止定时器
;DJNZ R0, Loop  ; 减1并检查R0，若不为0，回到Loop
;; 更新软件计数器和LED状态
;MOV R0, #2  ; 重新设置软件计数器
;RL A
;SJMP Next


; 方法二：中断方式
AJMP Main
ORG 001BH
AJMP Timer1
ORG 0030H

Main:
MOV A, #0FEH
MOV P2, A
MOV TMOD, #10H
MOV TH1, #3CH
MOV TL1, #0B0H
SETB TR1
SETB EA
SETB ET1
MOV R0, #2

Wait:
SJMP Wait  ; 等待中断

Timer1:
DJNZ R0, Skip  ; 减1并检查R0，若不为0，跳过
RL A
MOV P2, A
MOV R0, #2  ; 重新设置软件计数器为2
Skip:
; 重设Timer1
MOV TH1, #3CH
MOV TL1, #0B0H
RETI

END